#include "dvbinner.h"

#define MAX_SERVICE_NUM				1000

typedef struct tagSERVICEINFO
{ 
	struct tagSERVICEINFO	*next;
	dvb_service_t			sloc;
	unsigned char			bLock;	
	unsigned char			bUsed;	
	unsigned char			bRename;	
	char 				ServiceName[32];	
	char					volume;	
	char					StereoMode;	
	char					SerType;
	unsigned char			audioIndex;	
	unsigned int			nfrequency;//khz	
	unsigned char			nSublangIndex;
	unsigned char			bNetProg;
	char					proNetName[32];
	unsigned short			wLcn;
}SERVICEINFO,*PSERVICEINFO; 

int			bServiceListParaChg = 0;
int			newChannel = 0;
SERVICEINFO	ServiceList[MAX_SERVICE_NUM];
unsigned int ServiceList_Count=0;

int DVBServicesDBClear()
{
	memset(ServiceList, 0, sizeof(SERVICEINFO)*ServiceList_Count);
	ServiceList_Count=0;
	bServiceListParaChg = TRUE;
	return 0;
}

int DVBServicesDBClearNetProg()
{
	unsigned int i;
	PSERVICEINFO pstServiceList = NULL;
	unsigned int u32Cnt = 0;
	int ret;

	if(ServiceList_Count)
	{
		pstServiceList = (PSERVICEINFO)mwOsAllocMemory(sizeof(SERVICEINFO)*ServiceList_Count);
		if(pstServiceList)
		{
			for(i=0; i<ServiceList_Count; i++)
			{
				if(ServiceList[i].bNetProg == 0)
				{
					memcpy(&pstServiceList[u32Cnt], &ServiceList[i], sizeof(ServiceList[i]));
					u32Cnt++;
					bServiceListParaChg = TRUE;
				}
				else
				{
					DVBGroupDelService(&ServiceList[i].sloc);
				}
			}
			memcpy(ServiceList, pstServiceList, u32Cnt*sizeof(ServiceList[i]));
			ServiceList_Count = u32Cnt;
			ret = 0;
			mwDebug("DVBServicesDBClearNetProg() - found %d prog after clear net prog\r\n", ServiceList_Count);
			mwOsFreeMemory(pstServiceList);
		}
		else
		{
			mwError("DVBServicesDBClearNetProg() - malloc failed\r\n");
			ret = -1;
		}
	}
	return ret;
}

int DVBServicesDBAddItem(dvb_service_t* handle)
{
	mwDebug("DVBServicesDBAddItem() - add service handle[%d, %d, %d, %d]\r\n", handle->frequence, handle->netId, handle->tsId, handle->serviceId);
	ServiceList[ServiceList_Count].sloc=*handle;
	ServiceList[ServiceList_Count].bLock = 0;
	ServiceList[ServiceList_Count].bUsed = 0;
	ServiceList[ServiceList_Count].audioIndex = 0;
	ServiceList[ServiceList_Count].nSublangIndex = 0;
	ServiceList[ServiceList_Count].volume = 30;
	ServiceList[ServiceList_Count].StereoMode = 0;
	ServiceList[ServiceList_Count].bRename=0;
	ServiceList[ServiceList_Count].wLcn = 0;
	ServiceList_Count++;
	bServiceListParaChg = TRUE;
	return ServiceList_Count;
}

int DVBServicesDBListDelItem(dvb_service_t* handle)
{
	unsigned int i;
	int s32Ret = -1;

	if(handle)
	{
		for(i=0; i<ServiceList_Count; i++)
		{
			if(ServiceList[i].sloc.frequence==handle->frequence && ServiceList[i].sloc.netId==handle->netId 
				&& ServiceList[i].sloc.serviceId==handle->serviceId && ServiceList[i].sloc.tsId==handle->tsId)
			{
				mwDebug("DVBServicesDBListDelItem() - find item\r\n");
				ServiceList_Count--;
				break;
			}
		}
		if(i<=ServiceList_Count)
		{
			mwDebug("DVBServicesDBListDelItem() - delete service from service list success handle[%d, %d, %d]\r\n", handle->netId, handle->tsId, handle->serviceId);
			while(i<ServiceList_Count)
			{
				memcpy(&ServiceList[i], &ServiceList[i+1], sizeof(SERVICEINFO));
				i++;
			}
			memset(&ServiceList[i], 0, sizeof(SERVICEINFO)*(MAX_SERVICE_NUM-i));
			s32Ret = 0;
			bServiceListParaChg = TRUE;
		}
		else
		{
			mwDebug("DVBServicesDBListDelItem() - delete service from service list handle not found handle[%d, %d, %d]\r\n", handle->netId, handle->tsId, handle->serviceId);
			s32Ret = -1;
		}
	}
	return s32Ret;
}

PSERVICEINFO DVBServicesDBGetParamBySerHandle(dvb_service_t* handle)
{
	unsigned int i;
	
	if (handle)
	{
		for (i=0;i <ServiceList_Count;i++)
		{
			if((ServiceList[i].sloc.netId==handle->netId) && (ServiceList[i].sloc.tsId==handle->tsId)
			&& (ServiceList[i].sloc.serviceId==handle->serviceId) && (ServiceList[i].sloc.frequence==handle->frequence))
				return (&ServiceList[i]);
			bServiceListParaChg = TRUE;
		}
	}
	return NULL;
}

int DVBServicesDBReName(dvb_service_t* handle,char* pSzName,int len)
{
	unsigned int i;
	int s32Ret = -1;

	if(handle && len < sizeof(ServiceList[i].ServiceName))
	{
		for (i=0;i <ServiceList_Count;i++)
		{
			if((ServiceList[i].sloc.netId==handle->netId) && (ServiceList[i].sloc.tsId==handle->tsId)
				&& (ServiceList[i].sloc.serviceId==handle->serviceId) && (ServiceList[i].sloc.frequence==handle->frequence))
			{
				ServiceList[i].bRename = 1;
				memset(ServiceList[i].ServiceName, 0, sizeof(ServiceList[i].ServiceName));
				memcpy(ServiceList[i].ServiceName, pSzName, len);
				ServiceList[i].ServiceName[len] = 0;
				s32Ret = 0;
				bServiceListParaChg = TRUE;
			}
		}
	}
	return s32Ret;
}

int DvbServicesDBSetNetName(dvb_service_t* handle,char* pSzName,int len)
{
	unsigned int i;
	int s32Ret = -1;
	
	if(handle && len <= sizeof(ServiceList[0].proNetName))
	{
		for (i=0;i <ServiceList_Count;i++)
		{
			if((ServiceList[i].sloc.netId==handle->netId) && (ServiceList[i].sloc.tsId==handle->tsId)
				&& (ServiceList[i].sloc.serviceId==handle->serviceId) && (ServiceList[i].sloc.frequence==handle->frequence))
			{
				memset(ServiceList[i].proNetName, 0, sizeof(ServiceList[i].proNetName));
				memcpy(ServiceList[i].proNetName, pSzName, len+1);
				ServiceList[i].ServiceName[sizeof(ServiceList[i].proNetName)-1] = 0;
				s32Ret = 0;
				bServiceListParaChg = TRUE;
				s32Ret = -1;
			}
		}
	}
	else
	{
		mwError("DvbServicesDBSetNetName() - receive error param\r\n");
	}
	return s32Ret;
}

int DvbServicesDBSetNetFlag(dvb_service_t* handle, DVB_NETNAME_FLAG_T eType)
{
	unsigned int i;
	int s32Ret = -1;

	if(handle)
	{
		for (i=0; i<ServiceList_Count; i++)
		{
			if((ServiceList[i].sloc.netId==handle->netId) && (ServiceList[i].sloc.tsId==handle->tsId)
				&& (ServiceList[i].sloc.serviceId==handle->serviceId) && (ServiceList[i].sloc.frequence==handle->frequence))
			{
				ServiceList[i].bNetProg = eType;
				s32Ret = 0;
				bServiceListParaChg = TRUE;
			}
		}
	}
	return s32Ret;
}

int DvbServicesDBGetNetFlag(dvb_service_t* handle, unsigned char* pbNetProg)
{
	unsigned int i;
	int s32Ret = -1;

	if(handle && pbNetProg)
	{
		for (i=0;i <ServiceList_Count;i++)
		{
			if((ServiceList[i].sloc.netId==handle->netId) && (ServiceList[i].sloc.tsId==handle->tsId)
				&& (ServiceList[i].sloc.serviceId==handle->serviceId) && (ServiceList[i].sloc.frequence==handle->frequence))
			{
				*pbNetProg = ServiceList[i].bNetProg;
				s32Ret = 0;
			}
		}
	}
	return s32Ret;
}

int DvbServicesDBGetNetName(dvb_service_t* handle, char* pSzName, int len)
{
	unsigned int i;
	int s32Ret = -1;

	if(handle)
	{
		if(len > sizeof(ServiceList[i].proNetName))
			len = sizeof(ServiceList[i].proNetName);

		for (i=0;i <ServiceList_Count;i++)
		{
			if((ServiceList[i].sloc.netId==handle->netId) && (ServiceList[i].sloc.tsId==handle->tsId)
				&& (ServiceList[i].sloc.serviceId==handle->serviceId) && (ServiceList[i].sloc.frequence==handle->frequence))
			{
				memcpy(pSzName, ServiceList[i].proNetName, len);
				pSzName[len-1] = 0;
				s32Ret = 0;
			}
		}
	}
	else
	{
		mwError("DvbServicesDBGetNetName() - receive error param\r\n");
	}
	return s32Ret;
}

int DvbServicesDBGetLcn(dvb_service_t* handle)
{
	unsigned int i;
	int lcn = -1;
	int lcnflag = -1;//-1 == old icast1.0 0 == new icast3.0
	
	if(handle)
	{
		for (i = 0; i<ServiceList_Count; i++) 
		{
			if (ServiceList[i].wLcn != 0) {
				lcnflag = 0;
				break;
			}
		}
		
		for (i=0;i <ServiceList_Count;i++)
		{
			if((ServiceList[i].sloc.netId==handle->netId) && (ServiceList[i].sloc.tsId==handle->tsId)
				&& (ServiceList[i].sloc.serviceId==handle->serviceId) && (ServiceList[i].sloc.frequence==handle->frequence))
			{
				lcn = ServiceList[i].wLcn;
				if(lcn==0 && (ServiceList[0].wLcn==0&&ServiceList_Count>1) && lcnflag ==-1)
					lcn = DVBGetServiceIndex(handle);
				break;
			}
		}
	}
	else
	{
		mwError("DvbServicesDBGetLcn() - receive error param\r\n");
		return -1;
	}

	return lcn;
}

dvb_service_t* DVBServicesDBGetHandleByLcn(unsigned int u32Lcn)
{
	unsigned int i;
	dvb_service_t* handle = NULL;

	for (i=0;i <ServiceList_Count;i++)
	{
		if(ServiceList[i].wLcn == u32Lcn)
		{
			handle = &ServiceList[i].sloc;
		}
	}

	return handle;
}

int DVBServicesDBSetLcn(dvb_service_t* handle, unsigned int u32Lcn)
{
	int s32Ret = -1;
	unsigned int i;

	if(handle)
	{
		for (i=0;i <ServiceList_Count;i++)
		{
			if((ServiceList[i].sloc.netId==handle->netId) && (ServiceList[i].sloc.tsId==handle->tsId)
				&& (ServiceList[i].sloc.serviceId==handle->serviceId) && (ServiceList[i].sloc.frequence==handle->frequence))
			{
				ServiceList[i].wLcn = (unsigned short)u32Lcn;
				s32Ret = 0;
				bServiceListParaChg = TRUE;
			}
		}
	}
	else
	{
		mwError("DVBServicesDBSetLcn() receive error param\r\n");
	}
	
	return s32Ret;
}

int DVBServicesDBGetType(dvb_service_t* handle, unsigned int* pu32Type)
{
	PSERVICEINFO pService;
	int s32Ret = -1;

	if(handle && pu32Type)
	{
		pService = DVBServicesDBGetParamBySerHandle(handle);
		if(pService)
		{
			*pu32Type = pService->SerType;
		}
	}
	
	return s32Ret;
}

int DVBServicesDBSetType(dvb_service_t* handle, unsigned int u32Type)
{
	PSERVICEINFO pService;
	int s32Ret = -1;

	if(handle)
	{
		pService = DVBServicesDBGetParamBySerHandle(handle);
		if(pService)
		{
			pService->SerType = u32Type;
			bServiceListParaChg = TRUE;
		}
	}
	
	return s32Ret;
}

int DVBServicesDBGetAudioIndex(dvb_service_t* handle)
{
	PSERVICEINFO pService;
	
	pService = DVBServicesDBGetParamBySerHandle(handle);
	if(pService == NULL)
	{
		mwError("DVBServicesDBGetAudioIndex() - service not found! \r\n");		
		return -1;
	}
	return pService->audioIndex ;
}

int DVBServicesDBSetAudioIndex(dvb_service_t* handle, unsigned int u32Index)
{
	PSERVICEINFO pService;
	
	pService = DVBServicesDBGetParamBySerHandle(handle);
	if(pService == NULL)
	{
		mwError("DVBServicesDBSetAudioIndex() - service not found! \r\n");		
		return -1;
	}
	pService->audioIndex = u32Index;
	bServiceListParaChg = TRUE;

	return 0;
}

int DVBServicesDBSetSubLangIndex(dvb_service_t* handle, int index)
{
	PSERVICEINFO pService;
	int s32Ret = -1;
	
	if(handle)
	{
		pService = DVBServicesDBGetParamBySerHandle(handle);
		if(pService)
		{
			if(pService->nSublangIndex == index)
			{
				mwError("DVBServicesDBSetSubLangIndex() - found cur index equal\r\n");		
				return -1;
			}

			if(index == 0xff)
			{
				//dvb_subtitle_stop();
			}
			else
			{
				int subNum = 0;
				SUBTITLEINFO SubtitleInfo[20];
				subNum = DVBServiceGetSubtitleInfo(handle, SubtitleInfo);
				if(index >= subNum)
				{
					mwError("DVBServicesDBSetSubLangIndex() - error index %d\r\n",index);
					return -1;
				}
				
				if(pService->nSublangIndex ==0xff)
				{
					//dvb_subtitle_stop();
					//dvb_subtitle_start(handle,index);
				}
				else
				{
					//dvb_subtitle_switchLang(index);
				}		
			}
			pService->nSublangIndex = index;	
		}
		else
		{
			mwError("DVBServicesDBSetSubLangIndex() - found handle[%d, %d, %d, %d] not in service list\r\n", handle->frequence, handle->tsId, handle->netId, handle->serviceId);	
		}
	}
	else
	{
		mwError("DVBServicesDBSetSubLangIndex() handle %p, NULL\r\n", handle);	
	}
	
	return 0;
}

int DVBServicesDBGetSubLangIndex(dvb_service_t* handle)
{
	PSERVICEINFO pService;
	unsigned int u32Index;
	
	pService = DVBServicesDBGetParamBySerHandle(handle);
	if(pService)
	{
		u32Index = pService->nSublangIndex;
	}
	else
	{
		mwDebug("DVBServicesDBGetSubLangIndex() - found handle[%d, %d, %d, %d] not in service list\r\n", handle->frequence, handle->tsId, handle->netId, handle->serviceId);	
		u32Index = (unsigned int)-1;
	}
	return  u32Index;
}

int DVBServicesDBGetLock(dvb_service_t* SerHandle)
{
	PSERVICEINFO pServiceInfo;

	pServiceInfo = DVBServicesDBGetParamBySerHandle(SerHandle);
	if (pServiceInfo)
	{
		return pServiceInfo->bLock;
	}
	return -1;
}

int DVBServicesDBSetLock(dvb_service_t* SerHandle,int bLock)
{
	PSERVICEINFO pServiceInfo;
	int s32Ret = -1;

	pServiceInfo = DVBServicesDBGetParamBySerHandle(SerHandle);
	if (pServiceInfo)
	{
		if(pServiceInfo->bLock != bLock)
		{
			pServiceInfo->bLock=bLock;
			bServiceListParaChg = TRUE;
		}
		s32Ret = 0;
	}
	return s32Ret;
}

int DVBServicesDBGetUsed(dvb_service_t* SerHandle)
{
	PSERVICEINFO pServiceInfo;

	pServiceInfo = DVBServicesDBGetParamBySerHandle(SerHandle);
	if (pServiceInfo)
	{
		return pServiceInfo->bUsed;
	}
	return -1;
}

int DVBServicesDBSetUsed(dvb_service_t* SerHandle, int used)
{
	PSERVICEINFO pServiceInfo;
	int s32Ret = -1;

	pServiceInfo = DVBServicesDBGetParamBySerHandle(SerHandle);
	if (pServiceInfo)
	{
		if(pServiceInfo->bUsed != used)
		{
			pServiceInfo->bUsed=used;
			bServiceListParaChg = TRUE;
		}
		s32Ret = 0;
	}
	return s32Ret;
}

int DVBServicesDBSetVolume(dvb_service_t* SerHandle,int vol)
{
	PSERVICEINFO pServiceInfo;
	int s32Ret = -1;
	
	if(vol > MAX_VOLUME_VALUE)
		vol = MAX_VOLUME_VALUE;
	else if(vol < 0)
		vol = 0;
	
	pServiceInfo = DVBServicesDBGetParamBySerHandle(SerHandle);
	if (pServiceInfo)
	{
		pServiceInfo->volume=vol;
		bServiceListParaChg = TRUE;
		s32Ret = 0;
	}
	return s32Ret;
}

int DVBServicesDBGetVolume(dvb_service_t* SerHandle)
{
	PSERVICEINFO pServiceInfo;

	pServiceInfo = DVBServicesDBGetParamBySerHandle(SerHandle);
	if (pServiceInfo)
	{
		return pServiceInfo->volume;
	}
	return -1;
}

int DVBServicesDBSetStereoMode(dvb_service_t* SerHandle,int mode)
{
	PSERVICEINFO pServiceInfo;
	
	pServiceInfo = DVBServicesDBGetParamBySerHandle(SerHandle);
	if (pServiceInfo)
	{
		pServiceInfo->StereoMode = mode;
		bServiceListParaChg = TRUE;
		return 0;
	}
	return -1;
}

int DVBServicesDBGetStereoMode(dvb_service_t* SerHandle)
{
	PSERVICEINFO pServiceInfo;

	pServiceInfo = DVBServicesDBGetParamBySerHandle(SerHandle);
	if (pServiceInfo)
	{
		return pServiceInfo->StereoMode;
	}
	return -1;
}

int DvbServicesDBGetName(dvb_service_t* handle, char*provider, char*sname)
{
	int s32Ret = -1;
	PSERVICEINFO  pSerinfo=NULL;
	
	pSerinfo = DVBServicesDBGetParamBySerHandle(handle);
	if(pSerinfo)
	{
		if(pSerinfo->bRename)
		{
			*provider =0;
			memcpy(sname, pSerinfo->ServiceName, sizeof(pSerinfo->ServiceName));
			sname[sizeof(pSerinfo->ServiceName)-1]=0;
			s32Ret = 0;
		}
		else if(pSerinfo->bNetProg > 0)
		{
			mwDebug("DvbServicesDBGetName() - found net prog name\r\n");
			DvbServicesDBGetNetName(handle, sname, sizeof(pSerinfo->proNetName));
			if(pSerinfo->bNetProg == DVB_NETNAME_ORIGIN)
			{
				mwDebug("DvbServicesDBGetName() - DVB_NETNAME_ORIGIN\r\n");
				mwConvertString(sname, DVBStringLen(pSerinfo->proNetName), NULL);
				mwDebug("DvbServicesDBGetName() - convert %s end\r\n", sname);
			}
			if(provider)
				*provider =0;
			s32Ret = 0;
		}
		else
		{
			mwError("DvbServicesDBGetName() - get service list no name\r\n");
		}
	}
	else
	{
		mwError("DvbServicesDBGetName() - found handle[%d, %d, %d, %d] not exit\r\n", handle->frequence, handle->netId, handle->tsId, handle->serviceId);
		s32Ret = -1;
	}
	
	return s32Ret;
}

int DVBServicesDBSerialize(unsigned char* pu8Data, unsigned int* pu32Len)
{
	int s32Ret = -1;
	unsigned int u32Offset;
	unsigned int u32VerifyBytes;

	mwDebug("DVBServicesDBSerialize() - entry, pu8Data = %p, *pu32Len\r\n", pu8Data, pu32Len);
	if(pu8Data && pu32Len && *pu32Len > sizeof(ServiceList)+2*sizeof(unsigned int))
	{
		s32Ret = 0;
		u32VerifyBytes = VERIFIED_BYTES;
		memcpy(pu8Data, &u32VerifyBytes, sizeof(unsigned int));
		u32Offset = sizeof(unsigned int);
		memcpy(pu8Data+u32Offset, &ServiceList_Count, sizeof(unsigned int));
		u32Offset += sizeof(unsigned int);
		if(ServiceList_Count)
		{
			memcpy(pu8Data+u32Offset, ServiceList, sizeof(SERVICEINFO)*ServiceList_Count);
			u32Offset += sizeof(SERVICEINFO)*ServiceList_Count;
		}
		*pu32Len = u32Offset;
		bServiceListParaChg = 0;
	}
	else
	{
		mwError("DVBServicesDBSerialize() - receive error param, pu8Data = %p, pu32Len = %p\r\n", pu8Data, pu32Len);
	}
	mwDebug("DVBServicesDBSerialize() - return, s32Ret = %d\r\n", s32Ret);	
	
	return s32Ret;
}

int DVBServicesDBDeserialize(unsigned char* pu8Data, unsigned int* pu32Len)
{
	int s32Ret = -1;
	unsigned int u32VerifyBytes;
	unsigned int u32Offset;
	unsigned int i;

	mwDebug("DVBServicesDBDeserialize() - entry, pu8Data = %p, *pu32Len\r\n", pu8Data, pu32Len);
	if(pu8Data && pu32Len && *pu32Len >= 2*sizeof(unsigned int))
	{
		memcpy(&u32VerifyBytes, pu8Data, sizeof(unsigned int));
		if(u32VerifyBytes != VERIFIED_BYTES)
		{
			mwError("DVBServicesDBDeserialize() - verified byte error!!! \r\n");
			ServiceList_Count = 0;
			memset(ServiceList, 0, sizeof(ServiceList));
		}
		else
		{
			s32Ret = 0;
			u32Offset = sizeof(unsigned int);
			memcpy((unsigned char *)&ServiceList_Count, pu8Data+u32Offset, sizeof(unsigned int));
			u32Offset += sizeof(unsigned int);
			mwDebug("DVBServicesDBDeserialize() - program count=%d \r\n", ServiceList_Count);
			if (ServiceList_Count > MAX_SERVICE_NUM)
			{
				mwError("DVBServicesDBDeserialize() - program count=%d overflow\r\n",ServiceList_Count);
				ServiceList_Count =0;
				memset(ServiceList, 0, sizeof(ServiceList));
			}
			else
			{
				memcpy(ServiceList, pu8Data+u32Offset, sizeof(SERVICEINFO) * ServiceList_Count);
				u32Offset += sizeof(SERVICEINFO) * ServiceList_Count;
				for(i=0; i<ServiceList_Count; i++)
					mwDebug("DVBServicesDBDeserialize() - servicelist[%d] [netid:%d tsid:%d serviceid:%d]\r\n", i, ServiceList[i].sloc.netId, ServiceList[i].sloc.tsId, ServiceList[i].sloc.serviceId);
				s32Ret = 0;
				*pu32Len = u32Offset;
			}
		}
	}
	else
	{
		mwError("DVBServicesDBDeserialize() - receive error param, pu8Data = %p, pu32Len = %p\r\n", pu8Data, pu32Len);
	}
	mwDebug("DVBServicesDBDeserialize() - return, s32Ret = %d\r\n", s32Ret);
	
	return s32Ret;
}

int DVBServicesDBChanged()
{
	return bServiceListParaChg;
}

int DVBSevicesDBIsServiceExist(dvb_service_t* handle)
{
	int s32Ret = 0;
	PSERVICEINFO pstService;
	
	pstService = DVBServicesDBGetParamBySerHandle(handle);
	if(pstService)
		s32Ret = 1;
	
	return s32Ret;
}

